#pragma once

#include <math.h>
#include <iostream>

#define PI 3.141593f
#define HALF_CIRCLE_DEG 180.f
#define FULL_CIRCLE_DEG 360.f
#define EPSILON 0.0001f

/*
Check if two floats are close enough together to be equal.
@return	Wether or not the difference in the two floats are within EPSILON in value.
*/
inline bool FloatEquals(float f1, float f2) {
	return fabs(f1 - f2) <= EPSILON;
}

class Vector2D {
public: 
	/*
	Create a vector with 0 as coordinates.
	*/
	Vector2D();
	/*
	Create a vector with the given coordinates
	*/
	Vector2D(float x, float y);
	/*
	Destructor
	*/
	~Vector2D();

	float x, y; // values or coordinates

	/*
	Zero vector.
	*/
	static Vector2D Zero() { return Vector2D(0.f, 0.f); }
	/*
	Vector that goes right.
	*/
	static Vector2D Right() { return Vector2D(1.f, 0.f); }
	/*
	Vector that goes left.
	*/
	static Vector2D Left() { return Vector2D(-1.f, 0.f); }
	/*
	Vector that goes up.
	*/
	static Vector2D Up() { return Vector2D(0.f, 1.f); }
	/*
	Vector that goes down.
	*/
	static Vector2D Down() { return Vector2D(0.f, -1.f); }
	/*
	Normalized vector based on the given polar angle.
	@param	angle	Polar angle in degrees.
	@return	Normalized vector with the given polar angle.
	*/
	static Vector2D GetVectorByPolarAngle(float angle);

	/*
	Add a vector to the current one.
	@param	v		Vector to add to this one.
	*/
	void Add(const Vector2D& v);
	/*
	Add a value to the current vector.
	@param	x		Value to add in x.
	@param	y		Value to add in y.
	*/
	void Add(float x, float y);
	/*
	Substract a vector from the current one.
	@param	v		Vector to substract from this one.
	*/
	void Substract(const Vector2D& v);
	/*
	Scale the vector.
	@param	scl		Scale value to apply to the vector.
	*/
	void Scale(float scl);
	/*
	Dot product of the vector with the given other vector.
	@param	v		Vector to calculate the for product with.
	@return	Dot product value.
	*/
	float Dot(const Vector2D& v) const;
	/*
	Move the vector by the given offset vector.
	@param	v		Offset value to move the vector.
	*/
	void MoveBy(const Vector2D& offset);
	/*
	Move the vector by the given offset positions.
	@param	xOffset	Offset value to move the vector in x.
	@param	yOffset	Offset value to move the vector in y.
	*/
	void MoveBy(float xOffset, float yOffset);
	/*
	Get the polar angle of the vector.
	@return	The polar angle, in degrees, of the vector.
	*/
	float GetPolarAngle() const;
	/*
	Get the angle between the vector and the given other vector.
	@param	Second vector, to calculate the angle with.
	@return	Angle between the vectors, in degrees.
	*/
	float GetAngleBetween(const Vector2D& v) const;
	/*
	Get the length of the vector.
	@return	Length of the vector.
	*/
	float Length() const;
	/*
	Get the square of the length of the vector.
	@return	Square of the length of the vector.
	*/
	float LengthSq() const;
	/*
	Normalize the vector, making it a unit vector.
	*/
	void Normalize();
	/*
	Display the vector in the console.
	*/
	void Display() const;

	///////////////
	// Operators //
	///////////////
	bool operator==(const Vector2D& v) const;
	Vector2D operator*(float scale) const;
	Vector2D operator/(float scale) const;
	float operator*(const Vector2D& v) const;
	Vector2D operator+(const Vector2D& v) const;
	Vector2D operator-(const Vector2D& v) const;
	void operator*=(float scale);
	void operator/=(float scale);
	void operator+=(const Vector2D& v);
	void operator-=(const Vector2D& v);
};

